package com.symaster.backups.frame.element.table;

import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author yinmiao
 * @version 2024/2/5
 */
public class TableLayout implements LayoutManager {

    private final Table table;
    private final Dimension minimumLayoutSize = new Dimension(1, 1);
    private final List<Integer> columnWidths = new ArrayList<>();
    private final List<String> columnNames = new ArrayList<>();

    public TableLayout(Table table) {
        this.table = table;
    }

    public void addColumn(String columnName, int columnWidth) {
        addColumn(columnWidths.size(), columnName, columnWidth);
    }

    public void addColumn(int columnIndex, String columnName, int columnWidth) {
        columnWidths.add(columnIndex, columnWidth);
        columnNames.add(columnIndex, columnName);
    }

    public void removeColumn(int columnIndex) {
        columnWidths.remove(columnIndex);
        columnNames.remove(columnIndex);
    }

    public int getColumnWidth(int index) {
        Integer i = columnWidths.get(index);

        if (i == null || i < 0) {

            synchronized (table.getTreeLock()) {
                Component[] components = table.getComponents();

                int i1 = Arrays.stream(components).mapToInt(e -> {
                    if (!(e instanceof JComponent jComponent)) {
                        return -1;
                    }
                    if (!(jComponent.getLayout() instanceof TableLayoutItem tableLayoutItem)) {
                        return -1;
                    }
                    return tableLayoutItem.getColumnPreferredWidth(index);
                }).max().orElse(-1);

                if (i1 < 0) {
                    return 50;
                }
                return i1;
            }
        }
        return i;
    }

    public String getColumnLabel(int index) {
        return columnNames.get(index);
    }

    public int getColumnCount() {
        return columnWidths.size();
    }

    @Override
    public void addLayoutComponent(String name, Component comp) {

    }

    @Override
    public void removeLayoutComponent(Component comp) {

    }

    @Override
    public Dimension preferredLayoutSize(Container parent) {
        synchronized (parent.getTreeLock()) {
            Component[] components = parent.getComponents();
            int sum = Arrays.stream(components).mapToInt(e -> e.getPreferredSize().height).sum();

            return new Dimension(200, sum + 35);
        }
    }

    @Override
    public Dimension minimumLayoutSize(Container parent) {
        return minimumLayoutSize;
    }

    @Override
    public void layoutContainer(Container parent) {
        synchronized (parent.getTreeLock()) {
            Component[] components = parent.getComponents();
            Insets insets = parent.getInsets();
            int yOffset = insets.top + table.getHeadHeight() + (table.isVerticalDivider() ? 1 : 0);

            for (Component component : components) {
                int width = component.getPreferredSize().width;
                int height = component.getPreferredSize().height;
                component.setBounds(insets.left, yOffset, width, height);
                yOffset += height + (table.isVerticalDivider() ? 1 : 0);
            }
        }
    }
}
